package tds.model10.version2;

import org.apache.commons.lang3.SerializationUtils;

import java.io.*;

/**
 * @Company 杭州先锋电子技术股份有限公司
 * @ClassName ConcretePrototype
 * @Description java实现原型模式的类通过实现Cloneable接口
 * @author tds
 * @Date 2019/4/25 10:45
 * @version 1.0.0
 */
public class ConcretePrototype implements Cloneable,Serializable {

    private static final long serialVersionUID = 8204774638065446514L;

    private String attr;

    private SerialObject  obj;

    public SerialObject getObj() {
        return obj;
    }

    public void setObj(SerialObject obj) {
        this.obj = obj;
    }

    public String getAttr() {
        return attr;
    }

    public void setAttr(String attr) {
        this.attr = attr;
    }

    @Override
    public String toString() {
        return "ConcretePrototype{" +
                "attr='" + attr + '\'' +
                '}';
    }

    @Override
    protected ConcretePrototype clone() {
        Object clone = null;
        try {
            clone = super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
            throw new RuntimeException(this.getClass() + "不支持clone()方法，可能原因是没有实现Cloneable接口",e);
        }
        return (ConcretePrototype) clone;
    }


    /**
     * @Description 使用序列化技术实现深拷贝（还有另外两种我网上看到的方法，一个是SerializationUtils.clone方法，另一个是将
     *      obj转为json，再转为obj）
     * @param
     * @return tds.model10.version2.ConcretePrototype
     */
    public ConcretePrototype deepClone(){
        byte[] bytes;
        try(
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                ObjectOutputStream oos = new ObjectOutputStream(bos);
                )
        {
            oos.writeObject(this);
            bytes = bos.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("序列化对象" + this + "失败",e);
        }
        try(
                ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
                ObjectInputStream ois = new ObjectInputStream(bis);
             )
        {
            Object object = ois.readObject();
            return (ConcretePrototype) object;
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
            throw new RuntimeException("反序列化对象" + this + "失败",e);
        }
    }
}
